using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;

namespace SubSonic
{
    public class Setting
    {
        internal string ColumnName = "";
        internal string ParameterName = "";
        internal object Value;
        internal bool IsExpression = false;
        internal Update query;

        public SqlQuery EqualTo(object value)
        {
            Value = value;
            query.SetStatements.Add(this);
            return query;
        }

        [EditorBrowsable(EditorBrowsableState.Never)]
        public override bool Equals(object obj)
        {
            return base.Equals(obj);
        }

        [EditorBrowsable(EditorBrowsableState.Never)]
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        [EditorBrowsable(EditorBrowsableState.Never)]
        public override string ToString()
        {
            return base.ToString();
        }
    }

    public class Update : SqlQuery
    {
        internal List<Setting> SetStatements = new List<Setting>();


        #region .ctors

        private Update() {}

        public Update(TableSchema.Table tbl)
        {
            Init(tbl);
        }

        public Update(string tableName)
        {
            TableSchema.Table tbl = DataService.GetSchema(tableName, "");
            Init(tbl);
        }

        public Update(string tableName, string providerName)
        {
            TableSchema.Table tbl = DataService.GetSchema(tableName, providerName);
            Init(tbl);
        }

        private void Init(TableSchema.Table tbl)
        {
            if(tbl == null)
                throw new SqlQueryException("Can't find the table schema - please specify the provider if there is more than one, or check the spelling");
            provider = tbl.Provider;
            FromTables.Add(tbl);
            QueryCommandType = QueryType.Update;
        }

        #endregion


        #region SET

        public Setting Set(string columnName)
        {
            return CreateSetting(columnName, false);
        }

        public Setting Set(TableSchema.TableColumn col)
        {
            return CreateSetting(col.ColumnName, false);
        }

        public Setting SetExpression(string column)
        {
            return CreateSetting(column, true);
        }

        public Setting SetExpression(TableSchema.TableColumn col)
        {
            return CreateSetting(col.ColumnName, true);
        }

        private Setting CreateSetting(string columnName, bool isExp)
        {
            Setting s = new Setting();
            s.query = this;
            s.ColumnName = columnName;
            s.ParameterName = Utilities.Utility.PrefixParameter("up_" + columnName, provider);
            s.IsExpression = isExp;
            return s;
        }

        #endregion


        #region Execution

        public override int Execute()
        {
            int result;
            ISqlGenerator generator = GetGenerator();
            string sql = generator.BuildUpdateStatement();
            QueryCommand cmd = new QueryCommand(sql, this.provider.Name);

            //add in the commands
            foreach(Setting s in SetStatements)
                cmd.Parameters.Add(s.ParameterName, s.Value);

            //set the contstraints
            SetConstraintParams(cmd);

            try
            {
                result = DataService.ExecuteQuery(cmd);
            }
            catch(Exception x)
            {
                SqlQueryException ex = new SqlQueryException(x.Message);
                throw ex;
            }
            return result;
        }

        #endregion
    }
}